from django.core.exceptions import ValidationError
from django_celery_beat.models import CrontabSchedule, PeriodicTask
from dvadmin_celery.views.task import CronSlpit, CeleryCrontabScheduleSerializer, PeriodicTasksSerializer
from rest_framework import serializers

from apitest.models import EnvInfo, ProjectInfo, ModuleInfo, TestApiInfo, TestCase, TestApiResult
from dvadmin.utils.serializers import CustomModelSerializer


class EnvInfoSerializer(CustomModelSerializer):
    class Meta:
        model = EnvInfo
        fields = "__all__"


class ProjectInfoSerializer(CustomModelSerializer):
    """
    序列化器
    """

    class Meta:
        model = ProjectInfo
        fields = "__all__"


class ModuleInfoSerializer(CustomModelSerializer):
    """
    序列化器
    """
    project_name = serializers.CharField(source='project_belong.project_name', read_only=True)

    class Meta:
        model = ModuleInfo
        fields = "__all__"


class TestApiInfoSerializer(CustomModelSerializer):
    """
    序列化器
    """

    # project_name = serializers.CharField(source='project_belong.project_name', read_only=True)

    class Meta:
        model = TestApiInfo
        fields = "__all__"


class TestCaseSerializer(CustomModelSerializer):
    class Meta:
        model = TestCase
        fields = "__all__"

    def save(self, **kwargs):
        casedata = super().save(**kwargs)
        # 集成celry内部模块
        cron = self.get_initial().get("cron")
        if cron is not None:
            cron_data = CronSlpit(cron)
            scheduleSerializer = CeleryCrontabScheduleSerializer(data=cron_data)
            scheduleSerializer.is_valid(raise_exception=True)
            print(cron_data)
            schedule, created = CrontabSchedule.objects.get_or_create(**cron_data)
            body_data = {}
            body_data['name'] = casedata.case_name
            body_data['crontab'] = schedule.id
            body_data['enabled'] = False
            body_data['task'] = 'apitest.tasks.apiTask'
            body_data['kwargs'] = str({"id": casedata.id})
            taskserializer = PeriodicTasksSerializer(data=body_data, context={"crontab": schedule.id})
            taskserializer.is_valid(raise_exception=True)
            taskserializer.save()
            casedata.task_id = taskserializer.data.get("id")
            casedata.save()
        return casedata

    def update(self, instance, validated_data):
        print(self.initial_data)
        cron = self.initial_data.get('cron')
        try:
            task = PeriodicTask.objects.get(id=instance.task_id)
        except:
            print("没有关联task")
            return super().update(instance, validated_data)

        if instance.cron != cron and task is not None:
            cron_data = CronSlpit(cron)
            # serializer = CeleryCrontabScheduleSerializer(data=cron_data)
            # serializer.is_valid(raise_exception=False)
            schedule, created = CrontabSchedule.objects.get_or_create(**cron_data)

            task.crontab = schedule
            task.save()

        name = self.initial_data.get('case_name')
        if task.name != name:
            task.name = name
            task.save()
        return super().update(instance, validated_data)


class TestApiResultSerializer(CustomModelSerializer):
    class Meta:
        model = TestApiResult
        fields = "__all__"


# class TestApiParameterSerializer(CustomModelSerializer):
#     """
#     序列化器
#     """
#     #project_name = serializers.CharField(source='project_belong.project_name', read_only=True)
#
#     class Meta:
#         model = TestApiParameter
#         fields = "__all__"


class ExportTestApiInfoSerializer(CustomModelSerializer):
    """
    序列化器
    """
    project_name = serializers.CharField(source='project_belong.project_name', default="")
    module_name = serializers.CharField(source='module_belong.module_name', default="")
    method_name = serializers.CharField(source='get_method_display', default="")
    create_datetime = serializers.DateTimeField(
        format="%Y-%m-%d %H:%M:%S", required=False, read_only=True
    )

    class Meta:
        model = TestApiInfo
        fields = "__all__"


class TestApiInfoImportSerializer(CustomModelSerializer):

    def validate(self, attr):
        params = attr.get("params")
        jsonbody = attr.get("jsonbody")
        if params is not None and jsonbody is not None:
            raise ValidationError({'message': 'params 和jsonbody 只能填写一个'})
        projectObj = attr.get('project_belong')
        moduleBelong = attr.get('module_belong')
        if moduleBelong.project_belong.id != projectObj.id:
            raise ValidationError({'message': '所属模块不在工程里面'})
        return attr

    def save(self, **kwargs):
        name = self.get_initial().get("name")
        dbapi = TestApiInfo.objects.filter(name=name).first()
        if dbapi:
            # if self.get_initial().get('project_belong') is not None:
            #     project_belong= self.get_initial().get('project_belong')
            #     self.get_initial()['project_belong']=ProjectInfo.objects.get(pk=project_belong)
            # if self.get_initial().get('module_belong') is not None:
            #     module_belong = self.get_initial().get('module_belong')
            #     self.get_initial()['module_belong'] = ModuleInfo.objects.get(pk=module_belong)
            # dbapi = super().update(dbapi,self.get_initial())
            if self.get_initial().get('project_belong') is not None:
                dbapi.project_belong = ProjectInfo.objects.get(pk=self.get_initial().get('project_belong'))
            if self.get_initial().get('module_belong') is not None:
                dbapi.module_belong = ModuleInfo.objects.get(pk=self.get_initial().get('module_belong'))
            dbapi.url = self.get_initial().get('module_belong')
            dbapi.method = self.get_initial().get('method')
            dbapi.headers = self.get_initial().get('headers')
            dbapi.verification = self.get_initial().get('verification')
            dbapi.extract = self.get_initial().get('extract')
            dbapi.jsonbody = self.get_initial().get('jsonbody')
            dbapi.params = self.get_initial().get('params')
            params = self.initial_data.get("params")
            if params is not None:
                dbapi.params_type = 1
            jsonbody = self.initial_data.get("jsonbody")
            if jsonbody is not None:
                dbapi.params_type = 2
            testApiInfo = dbapi.save()
        else:
            testApiInfo = super().save(**kwargs)
            params = self.initial_data.get("params")
            if params is not None:
                testApiInfo.params_type = 1
            jsonbody = self.initial_data.get("jsonbody")
            if jsonbody is not None:
                testApiInfo.params_type = 2
                # 修改字段
            testApiInfo.save()

        return testApiInfo

    class Meta:
        model = TestApiInfo
        fields = "__all__"
